package jflowmap.util;

import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringBufferInputStream;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.filechooser.FileFilter;

import net.java.dev.designgridlayout.DesignGridLayout;
import edu.umd.cs.piccolo.PCanvas;

public final class CommentWindow extends JFrame implements ActionListener, ClipboardOwner {
	private static final long serialVersionUID = 1L;
	private final DesignGridLayout layout;
	private final List<Comment> comments;
	private final Exportable exportable;
	
	private final JButton exportGraphButton;
	private final JButton exportDataButton;
	
	private final JTextPane editor;
	private final JLabel dataPane;
	
	private static final String EXPORT_GRAPH_ACTION = "export-graph";
	private static final String EXPORT_DATA_ACTION = "export-data";
	
	public CommentWindow(String title, String commentee, List<Comment> comments) {
		this(title, commentee, comments, null);
	}
	
	public CommentWindow(String title, String commentee, List<Comment> comments, Exportable exportable) {
		super(title);
		layout = new DesignGridLayout(this);
		this.comments = comments;
		this.exportable = exportable;
		
		exportGraphButton = new JButton("Diagramm speichern unter");
		exportGraphButton.setActionCommand(EXPORT_GRAPH_ACTION);
		exportGraphButton.addActionListener(this);
		
		exportDataButton = new JButton("Daten in Zwischenablage kopieren");
		exportDataButton.setActionCommand(EXPORT_DATA_ACTION);
		exportDataButton.addActionListener(this);

		this.editor = new JTextPane();
		editor.setContentType("text/html");
		editor.setEditable(false);
		editor.setBackground(this.getBackground());

		StringBuilder builder = new StringBuilder();
		
		for (Comment c: this.comments) {
			builder.append("<h3>").append(c.getTitle()).append("</h3>")
			.append(c.getText()).append("<br/>");
		}

		editor.setText("<html>" + builder.toString() + "</html>");

		JScrollPane scroll = new JScrollPane(editor);
		scroll.setPreferredSize(new Dimension(300, 150));
		scroll.revalidate();
		

		String data = exportable.getData();
		dataPane = new JLabel();
		dataPane.setText("<html>"+exportable.getData()+"</html>");

		layout.row().grid().add(new JLabel("<html><h2>" + commentee + "</h2></html>"));
		if (data == null)
			layout.row().grid().add(scroll);
		else
			layout.row().grid().add(dataPane).add(scroll, 2);
		layout.row().right().add(exportDataButton, exportGraphButton);
	}
	
	public DesignGridLayout getDesignGridLayout () {
		return layout;
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		JFileChooser fc = new JFileChooser();
		
		if (EXPORT_GRAPH_ACTION.equals(e.getActionCommand())) {
			fc.setDialogTitle("Tortendiagramm als PNG exportieren");
			fc.setFileFilter(new FileFilter() {
				@Override 
				public boolean accept(File f) {
					if (f.getName().endsWith(".png"))
						return true;
					return false;
				}
				
				@Override
				public String getDescription() {
					return "PNG-Bilder";
				}
			});
			fc.setSelectedFile(new File(exportable.getExportName() + ".png"));
			fc.setApproveButtonText("Speichern");
			
		    int retVal = fc.showOpenDialog(this);
		    if (retVal == JFileChooser.APPROVE_OPTION) {
		        File f = fc.getSelectedFile();
		        this.exportGraph(f);
		        if (!f.getName().endsWith(".png")) {
		            f.renameTo(new File(f.getAbsolutePath() + ".png"));
		        }
		    } 


		} else if (EXPORT_DATA_ACTION.equals(e.getActionCommand())) {
			this.exportData();
		}
	}
	
	private void exportData() {
		StringBuilder builder = new StringBuilder();
		builder.append("<html><body>");
		builder.append(exportable.getData());
		for (Comment c: this.comments) {
			builder.append("<h3>").append(c.getTitle()).append("</h3>")
			.append(c.getText()).append("<br/>");
		}
		builder.append("</body></html>");
		
		HtmlSelection selection = new HtmlSelection(builder.toString());
		Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
		clipboard.setContents(selection, this);
	}

	private void exportGraph(File outputFile) {
		if (exportable != null) {
			final PCanvas exportNode = exportable.startExport();
			
			BufferedImage image = new BufferedImage(exportNode.getWidth(),
				exportNode.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
			
			exportNode.paint(image.getGraphics());
			
			try {
				ImageIO.write(image, "png", outputFile);
			} catch (IOException e) {
				e.printStackTrace();
			}
				
			exportable.endExport();
		}
	}

	private static class HtmlSelection implements Transferable {
		private static ArrayList<DataFlavor> htmlFlavors = new ArrayList<DataFlavor>();

		static {
			try {
				htmlFlavors.add(new DataFlavor("text/html;class=java.lang.String"));
				htmlFlavors.add(new DataFlavor("text/html;class=java.io.Reader"));
				htmlFlavors.add(new DataFlavor("text/html;charset=unicode;class=java.io.InputStream"));
			} catch (ClassNotFoundException ex) {
				ex.printStackTrace();
			}
		}

		private String html;

		public HtmlSelection(String html) {
			this.html = html;
		}

		public DataFlavor[] getTransferDataFlavors() {
			return (DataFlavor[]) htmlFlavors.toArray(new DataFlavor[htmlFlavors.size()]);
		}

		public boolean isDataFlavorSupported(DataFlavor flavor) {
			return htmlFlavors.contains(flavor);
		}

		public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException {
			if (String.class.equals(flavor.getRepresentationClass())) {
				return html;
			} else if (Reader.class.equals(flavor.getRepresentationClass())) {
				return new StringReader(html);
			} else if (InputStream.class.equals(flavor.getRepresentationClass())) {
				return new StringBufferInputStream(html);
			}
			throw new UnsupportedFlavorException(flavor);
		}
	} 

	
	@Override
	public void lostOwnership(Clipboard arg0, Transferable arg1) {
	}
}






